/*
 * Copyright (c) 2018-present, lmyooyo@gmail.com.
 *
 * This source code is licensed under the GPL license found in the
 * LICENSE file in the root directory of this source tree.
 */
package com.zhg.videorecord.encoder

import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.media.MediaCodec
import android.media.MediaFormat
import android.opengl.EGLContext
import com.zhg.videorecord.encoder.impl.VideoHardEncoderImpl
import com.zhg.videorecord.encoder.impl.VideoHardSurfaceEncoderImpl
import com.zhg.videorecord.encoder.impl.VideoX264EncoderImpl
import com.zhg.videorecord.entity.CodecContext
import java.nio.ByteBuffer

/**
 * desc: 音频与视频编码的基础接口
 */
interface Encoder : Camera.PreviewCallback ,SurfaceTexture.OnFrameAvailableListener{
    var onPreparedListener: OnPreparedListener?
    var onRecordListener: OnRecordListener?
    fun start()
    fun pause()
    fun stop()
    fun setOnSampleListener(listener: OnSampleListener)
    fun setPresentationTime(nsecs: Long)
    fun getOutputFormat(): MediaFormat

    interface OnSampleListener {
        fun onFormatChanged(encoder: Encoder, format: MediaFormat)
        fun onSample(encoder: Encoder, info: MediaCodec.BufferInfo, data: ByteBuffer)
    }

    interface OnStopListener {
        fun onStop()
    }

    interface OnPreparedListener {
        fun onPrepared(encoder: Encoder)
    }

    interface OnRecordListener {
        fun onRecord(encoder: Encoder, timeUs: Long)
    }

    class Builder(private val context: CodecContext,

                  private var onPreparedListener: OnPreparedListener? = null) {
        private var textureId: IntArray?=null
        private var eglContext: EGLContext?=null
        fun build(): Encoder {
            return if (CodecContext.CodecType.HARD == context.codecType) {
                //硬编码根据获取数据的方式也有两种类型
                if (CodecContext.PreviewDataType.PreviewCallback == context.previewDataType){
                    VideoHardSurfaceEncoderImpl(context,onPreparedListener)
                }else{
                    VideoHardEncoderImpl(context, textureId!!, eglContext!!, onPreparedListener)
                }
            } else {
                VideoX264EncoderImpl(context, textureId!!, eglContext!!, onPreparedListener)
            }
        }

        fun setOnPreparedListener(listener: OnPreparedListener): Builder {
            onPreparedListener = listener
            return this
        }
        fun setTextureId(_textureId: IntArray?):Builder{
            textureId=_textureId
            return this
        }
        fun setEglContext(_eglContext: EGLContext?):Builder{
            eglContext=_eglContext
            return this
        }
    }
}